package handler

import (
	"encoding/json"
	"errors"
	"go-test/src/com/miao/common/set"
	"go-test/src/com/miao/common/utils"
	"go-test/src/com/miao/server"
	"go-test/src/com/miao/server/context"
	"log"
	"reflect"
	"sync"
)

var HandlerMaps map[byte]BaseHandler
var once sync.Once

func RegisterHandlers(){
	once.Do(func() {
		HandlerMaps=make(map[byte]BaseHandler)
		HandlerMaps[login_req]=LoginBody{}
		HandlerMaps[heart_beat]=HeartBeatBody{}
	})
}

type Text1 struct {
	sync.RWMutex
	s map[string]*set.Set
	b string
}

func (text1 *Text1) Decode(buffer []byte,ctx *context.ChannelContext) (interface{},[]byte,error){
	length := len(buffer)
	if  length<headLength{
		return nil,buffer,nil
	}
	var bType =buffer[0]
	var bodyLength=utils.BytesToInt(buffer[1:headLength])
	if bodyLength<0 {
		return nil,buffer,errors.New("bodyLength  is not right, remote:"+ctx.Conn.RemoteAddr().String())
	}

	var neededLength=headLength+bodyLength
	if (length-neededLength)<0 {
		return nil,buffer,nil
	}else {
		imPacket:=ServerPacket{}
		imPacket.BType=bType
		if bodyLength>0{
			body :=buffer[headLength:bodyLength+headLength]
			imPacket.Body=body
		}
		return imPacket,buffer[headLength+bodyLength:],nil
	}

}

func (text1 *Text1) Handler(packet interface{},ctx *context.ChannelContext){
	serverPacket :=packet.(ServerPacket)
	btype := serverPacket.BType
	handler := HandlerMaps[btype]
	if handler==nil {
		log.Println(btype,"不存在")
		return
	}
	//处理业务
	handlerPacket(handler,serverPacket,ctx)
}



func (text1 *Text1)  Encode(packet interface{},ctx *context.ChannelContext) []byte{
	serverPacket:=packet.(ServerPacket)
	body:=serverPacket.Body
	buffer:=make([]byte,0)
	bodyBytesInt :=utils.IntToBytes(len(body))
	buffer= append(buffer, serverPacket.BType)
	buffer=append(buffer,bodyBytesInt...)
	if len(body)!=0 {
		buffer=append(buffer,body...)
	}
	return buffer
}

func (text1 *Text1) AfterConnected(ctx *context.ChannelContext)  {
	server.Log(ctx.Id)
}

func (text1 *Text1) BeforeClose(ctx *context.ChannelContext)  {
	server.Log(ctx.UserId,ctx.Group.List())
}

func handlerPacket(baseHandler BaseHandler,packet ServerPacket,channelContext *context.ChannelContext)  {
	typ := reflect.TypeOf(baseHandler)
	baseBody := reflect.New(typ).Interface()
	if len(packet.Body)!=0 {
		err := json.Unmarshal(packet.Body, &baseBody)
		if err!=nil {
			log.Println(err.Error())
			return
		}
	}
	baseBody.(BaseHandler).handler(packet,channelContext)
}